package com.ilop.sthome.utils;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.ilop.sthome.common.CommonId;
import com.ilop.sthome.common.command.SiterCommand;
import com.ilop.sthome.data.enums.DeviceTrigger;
import com.ilop.sthome.data.greenDao.AutomationBean;
import com.ilop.sthome.data.greenDao.DefaultBean;
import com.ilop.sthome.data.greenDao.DeviceInfoBean;
import com.ilop.sthome.data.bean.HistoryBean;
import com.ilop.sthome.data.greenDao.SceneBean;
import com.ilop.sthome.data.bean.WarnBean;
import com.ilop.sthome.utils.greenDao.utils.AutomationDaoUtil;
import com.ilop.sthome.utils.greenDao.utils.DeviceDaoUtil;
import com.ilop.sthome.utils.greenDao.utils.SceneDaoUtil;
import com.ilop.sthome.utils.system.AppUtil;
import com.ilop.sthome.utils.tools.ByteUtil;
import com.siterwell.familywellplus.R;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author skygge
 * @date 2020-03-02.
 * GitHub：javofxu@github.com
 * email：skygge@yeah.net
 * description：数据解析类
 */
public class CoderUtils {
    /**
     * 同步设备
     * @param deviceName 网关
     * @return CRC总长度 + 所有子设备状态+房间的CRC,空缺补0000
     */
    public static String getDeviceCRC(String deviceName) {
        List<DeviceInfoBean> allSubDevice = DeviceDaoUtil.getInstance().findAllSubDevice(deviceName);
        if (allSubDevice.size() > 0) {
            Map<Integer, String> subDevice = new HashMap<>();
            for (DeviceInfoBean e : allSubDevice) {
                if (e.getDevice_status()!=null && e.getRoom_id()!=null){
                    subDevice.put(e.getDevice_ID(), e.getDevice_status() + e.getRoom_id());
                }
            }
            int listLength = allSubDevice.get(allSubDevice.size() - 1).getDevice_ID();
            StringBuilder statusCRC = new StringBuilder();
            for (int i = 1; i <= listLength; i++) {
                if (subDevice.containsKey(i)) {
                    String crc = ByteUtil.stringToCRC(Objects.requireNonNull(subDevice.get(i)));
                    statusCRC.append(crc.toUpperCase());
                } else {
                    statusCRC.append("0000");
                }
            }
            String CRCLength = setCodeSupplement2Byte(Integer.toHexString(listLength*2 + 2));
            return CRCLength + statusCRC.toString();
        } else {
            return "00020000";
        }
    }

    /**
     * 获取系统时区
     * @return timezone
     */
    public static String getTimeZone(){
        int timeZone = AppUtil.getTimeZone();
        if (timeZone>=0 && timeZone<10){
            return "000" + timeZone;
        }else if (timeZone >= 10){
            return "00" + timeZone;
        }else if (timeZone > -10){
            return "010" + Math.abs(timeZone);
        }else {
            return "01" + Math.abs(timeZone);
        }
    }

    /**
     * 同步设备名称
     * @param deviceName 网关
     * @return CRC
     */
    public static String getDeviceNameCRC(String deviceName) {
        List<DeviceInfoBean> allSubDevice = DeviceDaoUtil.getInstance().findAllSubDevice(deviceName);
        if (allSubDevice.size() > 0) {
            int listLength = allSubDevice.get(allSubDevice.size() - 1).getDevice_ID();
            List<Integer> deviceId = new ArrayList<>();
            for (DeviceInfoBean e : allSubDevice) {
                deviceId.add(e.getDevice_ID());
            }
            StringBuilder statusCRC = new StringBuilder();
            for (int i = 1; i <= listLength; i++) {
                if (deviceId.contains(i)) {
                    if(!TextUtils.isEmpty(allSubDevice.get(deviceId.indexOf(i)).getSubdeviceName())){
                        String asciiName = CoderUtils.getAscii(allSubDevice.get(deviceId.indexOf(i)).getSubdeviceName());
                        String crc = ByteUtil.nameToCRC(asciiName).toUpperCase();
                        statusCRC.append(crc);
                    }else{
                        statusCRC.append("0000");
                    }
                } else {
                    statusCRC.append("0000");
                }
            }
            String CRCLength = setCodeSupplement2Byte(Integer.toHexString(listLength*2 + 2));
            return CRCLength + statusCRC.toString();
        } else {
            return("00020000");
        }
    }


    /**
     * 同步场景
     * @param deviceName 网关
     * @return CRC
     */
    public static String getSceneCRC(String deviceName){
        StringBuilder getSceneCRC = new StringBuilder();
        List<SceneBean> sceneList = SceneDaoUtil.getInstance().findAllScene(deviceName);
        int sceneIdSize = sceneList.size();
        if(sceneList.size()>0){
            for (int i = 0; i < sceneIdSize; i++) {
                SceneBean sceneBean = sceneList.get(i);
                if (TextUtils.isEmpty(sceneBean.getCode())){
                    getSceneCRC.append("0000");
                }else {
                    getSceneCRC.append(sceneBean.getCode());
                }
            }
            String crcLength = Integer.toHexString(sceneIdSize*2+2);
            return setCodeSupplement2Byte(crcLength) + getSceneCRC.toString();
        }else{
            return "0000";
        }
    }

    /**
     * 自动化生效位
     * @param deviceName 网关
     * @return 所有自动化
     */
    public static String getAutomationCode(String deviceName){
        List<Integer> autoId = AutomationDaoUtil.getInstance().findAllMid(deviceName);
        if (autoId.size()>0) {
            int autoSize = autoId.size();
            int autoMax = Collections.max(autoId);
            String[] array = new String[autoMax/8+1];
            for (int i = 0; i <= autoMax/8; i++) {
                array[i] = "00000000";
            }
            StringBuilder fullCode = new StringBuilder();
            for (int i = 0; i < autoSize; i++) {
                int position = autoId.get(i)/8;
                int remainder = autoId.get(i)%8;
                if (remainder == 0){
                    remainder = 8;
                }
                for (int j = 0; j < array.length; j++) {
                    if (j == position){
                        StringBuilder index = new StringBuilder(array[j]);
                        index.replace(remainder-1, remainder, "1");
                        array[j] = index.toString();
                    }
                }
            }
            for (String code:array) {
                StringBuilder index = new StringBuilder(code);
                fullCode.append(setCodeSupplement1Byte(Integer.toHexString(Integer.parseInt(index.reverse().toString(), 2))));
            }
            return fullCode.toString();
        }else {
            return "00";
        }
    }

    /**
     * 生效自动化CRC校验码，page1
     * @param crc 所有自动化CRC
     * @return page1
     */
    public static String getAutomationCRCPage1(List<String> crc){
        StringBuilder index = new StringBuilder();
        int pageSize = crc.size();
        for (int i = 0; i < pageSize; i++) {
            index.append(crc.get(i));
        }
        int crcLength = index.length()/2 + 2;
        String fullLength = setCodeSupplement2Byte(Integer.toHexString(crcLength));
        return fullLength + index.toString();
    }

    /**
     * 生效自动化CRC校验码，page2
     * @param crc 所有自动化CRC
     * @return page1
     */
    public static String getAutomationCRCPage2(List<String> crc){
        StringBuilder index = new StringBuilder();
        int pageSize = crc.size();
        for (int i = 128; i < pageSize; i++) {
            index.append(crc.get(i));
        }
        int crcLength = index.length()/2 + 2;
        String fullLength = setCodeSupplement2Byte(Integer.toHexString(crcLength));
        return fullLength + index.toString();
    }

    /**
     * 新增/修改场景（code=23）
     * @param sceneBean 场景
     * @return code
     */
    public static String increaseScene(SceneBean sceneBean){
        String sid = setCodeSupplement1Byte(Integer.toHexString(sceneBean.getSid()));
        int colorNum = Integer.parseInt(sceneBean.getColor().substring(1));
        String color = setCodeSupplement1Byte(Integer.toHexString(colorNum));
        String theme = "FFFFFFFF";
        String name;
        if (sceneBean.getSid()<3){
            name = "40404040404040404040404040404024";
        }else {
            name = CoderUtils.getAscii(sceneBean.getModleName());
        }
        String fullCode =  sid + color + theme + name;
        String crc = ByteUtil.stringToCRC(fullCode);
        return fullCode + crc;
    }

    /**
     * 新增自动化
     * @param sid 场景映射
     * @param input 输入设备
     * @param output 输出设备
     * @return 自动化code
     */
    public static String getNewCode(String sid, List<DeviceInfoBean> input, List<DeviceInfoBean> output){
        // mid 自动化编号（新增发送FFFF,修改发网关应答ID）
        //输入设备数据
        String inputCode = getAutoInputCode(input);
        //输出设备数据
        String outputCode = getAutoOutputCode(output);
        //自动化总长度
        int length = getAutomationLength(inputCode.length()/2, outputCode.length()/2);
        String lengthCode = setCodeSupplement2Byte(Integer.toHexString(length));
        //映射场景
        String sceneCode = setCodeSupplement2Byte(sid);
        //推荐自动化序号（00/01）
        String isRecommend = "00";
        //输入设备个数
        String inputSize = setCodeSupplement1Byte(Integer.toHexString(input.size()));
        //输出设备个数
        String outputSize = setCodeSupplement1Byte(Integer.toHexString(output.size()));
        //次校验码
        String secondCode = lengthCode + sceneCode + isRecommend + inputSize + outputSize + inputCode;
        String secondCRC = ByteUtil.stringToCRC(secondCode);
        //返回自动化code
        return secondCode + secondCRC + outputCode;
    }

    /**
     * 新增常用功能自动化
     * @param defaultBean 常用功能
     * @return
     */
    public static String getNewCode(DefaultBean defaultBean){
        //输入设备数据
        String inputCode = defaultBean.getDeviceType()+ defaultBean.getDeviceId()+defaultBean.getInputCode();
        //输出设备数据
        String outputCode = defaultBean.getOutputCode();
        //自动化总长度
        int length = getAutomationLength(inputCode.length()/2, outputCode.length()/2);
        String lengthCode = setCodeSupplement2Byte(Integer.toHexString(length));
        //映射场景
        String sceneCode = setCodeSupplement2Byte(defaultBean.getMapping());
        //推荐自动化序号
        String isRecommend = defaultBean.getRecommendId();
        //输入设备个数
        String inputSize = setCodeSupplement1Byte(Integer.toHexString(1));
        //输出设备个数
        String outputSize = setCodeSupplement1Byte(Integer.toHexString(outputCode.length()>14?2:1));
        //次校验码
        String secondCode = lengthCode + sceneCode + isRecommend + inputSize + outputSize + inputCode;
        String secondCRC = ByteUtil.stringToCRC(secondCode);
        //返回自动化code
        return secondCode + secondCRC + outputCode;
    }

    /**
     * 新增常用功能自动化
     * @param sid 场景映射
     * @param input 输入设备
     * @param output 输出设备
     * @return 自动化code
     */
    public static String getNewCode(String sid, String recommendId, List<DeviceInfoBean> input, List<DeviceInfoBean> output){
        // mid 自动化编号（新增发送FFFF,修改发网关应答ID）
        //输入设备数据
        String inputCode = getAutoInputCode(input);
        //输出设备数据
        String outputCode = getAutoOutputCode(output);
        //自动化总长度
        int length = getAutomationLength(inputCode.length()/2, outputCode.length()/2);
        String lengthCode = setCodeSupplement2Byte(Integer.toHexString(length));
        //映射场景
        String sceneCode = setCodeSupplement2Byte(sid);
        //推荐自动化序号（00/01）
        String isRecommend = recommendId;
        //输入设备个数
        String inputSize = setCodeSupplement1Byte(Integer.toHexString(input.size()));
        //输出设备个数
        String outputSize = setCodeSupplement1Byte(Integer.toHexString(output.size()));
        //次校验码
        String secondCode = lengthCode + sceneCode + isRecommend + inputSize + outputSize + inputCode;
        String secondCRC = ByteUtil.stringToCRC(secondCode);
        //返回自动化code
        return secondCode + secondCRC + outputCode;
    }

    /**
     * 新增插座定时自动化（网关定时+插座动作）
     * @param outputStatus 插座设备动作
     * @return
     */
    public static String getNewCode(String recommendId, String status, String outputStatus){
        //输入设备数据
        String inputCode = "FFFF" + "0000" + status;
        //输出设备数据
        String outputCode = outputStatus;
        //自动化总长度
        int length = getAutomationLength(inputCode.length()/2, outputCode.length()/2);
        String lengthCode = setCodeSupplement2Byte(Integer.toHexString(length));
        //映射场景
        String sceneCode = "7FFF";
        //推荐自动化序号
        String isRecommend = recommendId;
        //输入设备个数
        String inputSize = "01";
        //输出设备个数
        String outputSize = "01";
        //次校验码
        String secondCode = lengthCode + sceneCode + isRecommend + inputSize + outputSize + inputCode;
        String secondCRC = ByteUtil.stringToCRC(secondCode);
        //返回自动化code
        return secondCode + secondCRC + outputCode;
    }

    /**
     * 新增插座联动自动化（输入动作+插座动作）
     * @param input 输入设备
     * @param output 输出设备
     * @return 自动化code
     */
    public static String getNewCodeLinkage(String recommendId, List<DeviceInfoBean> input, List<DeviceInfoBean> output){
        // mid 自动化编号（新增发送FFFF,修改发网关应答ID）
        //输入设备数据
        String inputCode = getAutoInputCode(input);
        //输出设备数据
        String outputCode = getAutoOutputCode(output);
        //自动化总长度
        int length = getAutomationLength(inputCode.length()/2, outputCode.length()/2);
        String lengthCode = setCodeSupplement2Byte(Integer.toHexString(length));
        //映射场景
        String sceneCode = "0FFF";
        //推荐自动化序号（00/01）
        String isRecommend = recommendId;
        //输入设备个数
        String inputSize = setCodeSupplement1Byte(Integer.toHexString(input.size()));
        //输出设备个数
        String outputSize = setCodeSupplement1Byte(Integer.toHexString(output.size()));
        //次校验码
        String secondCode = lengthCode + sceneCode + isRecommend + inputSize + outputSize + inputCode;
        String secondCRC = ByteUtil.stringToCRC(secondCode);
        //返回自动化code
        return secondCode + secondCRC + outputCode;
    }

    /**
     * 获取输入设备code
     * @param input 输入设备
     * @return code
     */
    public static String getAutoInputCode(List<DeviceInfoBean> input){
        StringBuilder inputCode = new StringBuilder();
        for (DeviceInfoBean device : input) {
            String type;
            String deviceId;
            if ("CLICK".equals(device.getDevice_type()) || "TIMER".equals(device.getDevice_type())){
                type = "FFFF";
                deviceId = "0000";
            }else {
                type = device.getDevice_type();
                deviceId = setCodeSupplement2Byte(Integer.toHexString(device.getDevice_ID()));
            }
            String action = String.valueOf(device.getDevice_status());
            inputCode.append(type).append(deviceId).append(action);
        }
        return inputCode.toString();
    }

    /**
     * 获取输出设备code
     * @param output 输出设备
     * @return code
     */
    public static String getAutoOutputCode(List<DeviceInfoBean> output){
        StringBuilder outputCode = new StringBuilder();
        for (DeviceInfoBean device : output) {
            String type;
            String deviceId;
            String action;
            if ("GATEWAY".equals(device.getDevice_type())){
                type = "FFFF";
                deviceId = "0000";
                action = String.valueOf(device.getDevice_status());
            }else if ("PHONE".equals(device.getDevice_type())){
                type = "FFFF";
                deviceId = "0000";
                action = "82FFFF";
            }else {
                type = device.getDevice_type();
                deviceId = setCodeSupplement2Byte(Integer.toHexString(device.getDevice_ID()));
                action = String.valueOf(device.getDevice_status());
            }
            outputCode.append(type).append(deviceId).append(action);
        }
        return outputCode.toString();
    }

    /**
     * 该自动化的总长度，但不包括总校验码
     * @return length
     */
    public static int getAutomationLength(int inputLength, int outputLength){
        return 2+2+2+1+1+1+inputLength+2+outputLength;
    }

    /**
     * 获取场景映射二进制
     * @param sceneId
     * @return
     */
    public static String setSceneCode(int sceneId){
        StringBuilder index = new StringBuilder();
        for (int i = 0; i < 12; i++) {
            if (i == sceneId){
                index.append("1");
            }else {
                index.append("0");
            }
        }
        return index.reverse().toString();
    }

    /**
     * 获取网关的动作代码
     * @param status 动作1(30是静音，单独处理，与报警分开）
     * @param delay 延时
     * @param hasDelay 是否有延时操作
     * @return 完整的动作代码
     */
    public static String getGatewayActionCode(String status, String delay, boolean hasDelay){
        if (hasDelay){
            if ("30".equals(status)){
                return "32"+ delay;
            }else if ("4".equals(status.substring(0,1))){
                return "43" + status.substring(2,4) + delay;
            }else if ("5".equals(status.substring(0,1))){
                return "53" + status.substring(2,4) + delay;
            }else {
                return "23" + status + delay;
            }
        }else {
            if ("30".equals(status)){
                return "30";
            }else if ("4".equals(status.substring(0,1))){
                return status;
            }else if ("5".equals(status.substring(0,1))){
                return status;
            }else {
                return "21" + status;
            }
        }
    }
    /**
     * 获取子设备的动作代码
     * @param status 动作1
     * @param delay 延时
     * @param hasDelay 是否有延时操作
     * @return 完整的动作代码
     */
    public static String getSubDeviceActionCode(String status, String delay, boolean hasDelay){
        if (hasDelay){
            int statusCode = Integer.parseInt(status) +2;
            return statusCode + delay;
        }else {
            return status;
        }
    }

    /**
     * 解析自动化同步代码
     * @param code 网关返回代码
     * @param deviceName 网关
     */
    public static AutomationBean analysisFullCode(String code, String deviceName){
        try{
            AutomationBean mAutomation = new AutomationBean();
            int autoId = Integer.parseInt(code.substring(0,4), 16);
            mAutomation.setAutomationOnly(deviceName + "-" + autoId);
            mAutomation.setDeviceName(deviceName);
            mAutomation.setMid(autoId);
            mAutomation.setCode(code);//自动化代码

            String sceneCode = code.substring(8, 12);//场景映射
            mAutomation.setSceneId(sceneCode);

            String isRecommend = code.substring(12, 14);//是否推荐自动化
            mAutomation.setReserve(isRecommend);

            String crcCode = code.substring(code.length()-4);
            mAutomation.setCrcCord(crcCode);

            int inputSize = Integer.parseInt(code.substring(14, 16),16);//输入设备个数
            int outputSize = Integer.parseInt(code.substring(16, 18),16);//输出设备个数

            String firstType = code.substring(18, 26);//第一个输入设备的type+deviceId 用于判断常用功能
            mAutomation.setName(firstType);

            int positionIn = 18;//输入设备开始
            List<DeviceInfoBean> deviceInList = new ArrayList<>();
            for (int i = 0; i < inputSize; i++) {
                DeviceInfoBean device = new DeviceInfoBean();
                String deviceType = code.substring(positionIn, positionIn+4);
                int deviceId = Integer.parseInt(code.substring(positionIn+4, positionIn+8),16);
                String action = code.substring(positionIn+8, positionIn+10);
                if ("FFFF".equals(deviceType) && deviceId == 0){
                    if ("03".equals(action)){
                        device.setDevice_type("TIMER");
                        device.setDevice_ID(deviceId);
                    }else if ("10".equals(action)){
                        device.setDevice_type("CLICK");
                        device.setDevice_ID(deviceId);
                    }else {
                        device.setDevice_type("GATEWAY");
                        device.setDevice_ID(deviceId);
                    }
                }else {
                    device.setDevice_type(deviceType);
                    device.setDevice_ID(deviceId);
                }
                int actionLength = positionIn+10+Integer.parseInt(action.substring(1))*2;
                String fullAction = code.substring(positionIn+8, actionLength);
                device.setDevice_status(fullAction);
                device.setDeviceName(deviceName);
                deviceInList.add(device);
                positionIn = actionLength;
            }
            mAutomation.setInputList(deviceInList);

            int positionOut = positionIn + 4;//输出设备开始
            List<DeviceInfoBean> deviceOutList = new ArrayList<>();
            for (int i = 0; i < outputSize; i++) {
                DeviceInfoBean device = new DeviceInfoBean();
                String deviceType = code.substring(positionOut, positionOut+4);
                int deviceId = Integer.parseInt(code.substring(positionOut+4, positionOut+8),16);
                String action = code.substring(positionOut+8, positionOut+10);
                if ("FFFF".equals(deviceType) && deviceId == 0){
                    if ("82".equals(action)){
                        device.setDevice_type("PHONE");
                        device.setDevice_ID(deviceId);
                    }else {
                        device.setDevice_type("GATEWAY");
                        device.setDevice_ID(deviceId);
                    }
                }else {
                    device.setDevice_type(deviceType);
                    device.setDevice_ID(deviceId);
                }
                int actionLength = positionOut+10+Integer.parseInt(action.substring(1))*2;
                String fullAction = code.substring(positionOut+8, actionLength);
                device.setDevice_status(fullAction);
                device.setDeviceName(deviceName);
                deviceOutList.add(device);
                positionOut = actionLength;
            }
            mAutomation.setOutputList(deviceOutList);
            AutomationDaoUtil.getInstance().insertOrReplace(mAutomation);
            return mAutomation;
        }catch (Exception e){
            return null;
        }
    }

    /**
     * 解析自动化生效位
     * @param deviceName 网关
     * @param code 64byte,表示网关所有自动化生效位
     */
    public static void analysisFinalCode(String deviceName, String code){
        String newCode = code.replaceAll("(00)+$", "");
        if (!TextUtils.isEmpty(newCode) && newCode.length()>2) {
            Log.i("AAA", "analysisFinalCode: " + newCode);
            int size = newCode.length() / 2;
            AutomationDaoUtil.getInstance().deleteByInvalid(size * 8);
            for (int i = 0; i < size; i++) {
                String hex = newCode.substring(i * 2, i * 2 + 2);
                if (!"FF".equals(hex)) {
                    String binary = Integer.toBinaryString(Integer.parseInt(hex, 16));
                    String newBinary = setCodeSupplement4Byte(binary);
                    Log.i("BBB", "analysisFinalCode: " + newBinary);
                    for (int j = 0; j < 8; j++) {
                        int num = Integer.parseInt(newBinary.substring(j, j + 1));
                        if (num == 0) {
                            int mid = (i + 1) * 8 - j;
                            Log.i("CCC", "analysisFinalCode: " + mid);
                            AutomationDaoUtil.getInstance().deleteByMid(mid, deviceName);
                        }
                    }
                }
            }
        }
    }

    /**
     * 解析网关的动作代码
     * @param status 十六进制代码
     * @return 动作状态
     */
    public static String analysisGatewayActionCode(Context context, String deviceName, String status){
        String[] mCode = context.getResources().getStringArray(R.array.EE_DEV_GATEWAY);
        String[] mState = context.getResources().getStringArray(R.array.gateway_actions);
        String[] mSceneName = new String[]{context.getString(R.string.home_mode), context.getString(R.string.out_mode),context.getString(R.string.sleep_mode)};
        if ("3".equals(status.substring(0,1))){
            return mState[3];
        }else if ("4".equals(status.substring(0,1))){
            String action = status.substring(2, 4);
            for (int i = 4; i < mCode.length; i++) {
                String code = mCode[i].substring(2, 4);
                if (code.equals(action)){
                    return mState[i];
                }
            }
        }else if ("5".equals(status.substring(0,1))){
            int sceneId = Integer.parseInt(status.substring(2,4), 16);
            SceneBean sceneBean = SceneDaoUtil.getInstance().findSceneBySid(sceneId, deviceName);
            String sceneName = sceneId>2 ? sceneBean.getModleName() : mSceneName[sceneId];
            return context.getString(R.string.switch_to) + ":\t" + sceneName;
        } else {
            String action = status.substring(2, 4);
            for (int i = 0; i < mCode.length; i++) {
                if (mCode[i].equals(action)){
                    return mState[i];
                }
            }
        }
        return null;
    }

    /**
     * 解析输入条件
     * @param context 上下文
     * @param type 设备类型
     * @param code 输入代码
     * @return 输入文案
     */
    public static String getDeviceTypeMsg(Context context, String type, String code){
        String[] mTrigger = context.getResources().getStringArray(Objects.requireNonNull(DeviceTrigger.getType(type)).getCode());
        String[] str = context.getResources().getStringArray(Objects.requireNonNull(DeviceTrigger.getType(type)).getState());
        if (code.length() >= 6){
            code = code.substring(0,1) + "0";
        }
        for (int j = 0; j < mTrigger.length; j++) {
            if (mTrigger[j].equals(code)) {
                return str[j];
            }
        }
        if ("40".equals(code) || "0111".equals(code)){
            return context.getString(R.string.Illegal_demolition);
        }
        return context.getString(R.string.lack_of_equipment);
    }

    /**
     * 解析延时
     * @param context 上下文
     * @param time 时间
     * @return
     */
    public static String getDelayTime(Context context, String time){
        int minute = Integer.parseInt(time.substring(0,2), 16);
        int second = Integer.parseInt(time.substring(2,4), 16);
        String minuteDw = context.getString(R.string.device_setup_record_minute);
        String secondDw = context.getString(R.string.device_setup_record_second);
        if (minute == 0 && second == 0) {
            return null;
        } else if (minute == 0 && second > 0) {
            return second + secondDw;
        } else if (minute > 0 && second == 0) {
            return minute + minuteDw;
        } else {
            return minute + minuteDw + second + secondDw;
        }
    }

    /**
     * 解析定时
     * @param context 上下文
     * @param timer 定时代码
     * @return 定时文案
     */
    public static String getTimerMsg(Context context, String timer){
        String init_week = timer.substring(2, 4);
        String week = CoderUtils.getWeekInfo(context, init_week);
        int hour = Integer.parseInt(timer.substring(4, 6), 16);
        int min = Integer.parseInt(timer.substring(6), 16);
        String time = CoderUtils.setCodeSupplement1Byte(String.valueOf(hour))
                + ":"+ CoderUtils.setCodeSupplement1Byte(String.valueOf(min)) ;
        return time + "\t\t" +week;
    }

    /**
     * 解析温湿度上下限设置
     * @param context 上下文
     * @param humiture 温湿度code
     * @return 条件文案
     */
    public static String getHumitureMsg(Context context, String humiture){
        if ("1100".equals(humiture)){
            return context.getString(R.string.ali_temp) + context.getString(R.string.lower_than) +"0℃";
        }else if ("410F".equals(humiture)){
            return context.getString(R.string.hum) + context.getString(R.string.lower_than) +"15%";
        }else {
            String action = humiture.substring(0, 2);
            String tempText, humText;
            String code = humiture.substring(2, 4);
            switch (action){
                case "01"://温度高于-上限
                    tempText = getTempText(context,false, code);
                    return tempText + "℃";
                case "11"://温度低于-下限
                    tempText = getTempText(context,true, code);
                    return tempText + "℃";
                case "31"://湿度高于-上限
                    humText = getHumText(context,false, code);
                    return  humText + "%";
                case "41"://湿度低于-下限
                    humText = getHumText(context,true, code);
                    return  humText + "%";
                default:
                    return context.getString(R.string.temperature_triggering_mode);
            }
        }
    }

    private static String getTempText(Context context, boolean isLow, String tempCode){
        String[] mTrigger = context.getResources().getStringArray(R.array.thtrigger_method);
        String[] mStyle = context.getResources().getStringArray(R.array.thtrigger_style);
        if (isLow) {
            int temp = Integer.parseInt(tempCode, 16);
            String finalTemp = String.valueOf(temp);
            if (temp > 128) {
                temp = 256 - temp;
                finalTemp = "-" + temp;
            }
            return mTrigger[0] + mStyle[0] + finalTemp;
        } else {
            int temp = Integer.parseInt(tempCode, 16);
            String finalTemp = String.valueOf(temp);
            if (temp > 128) {
                temp = 256 - temp;
                finalTemp = "-" + temp;
            }
            return mTrigger[0] + mStyle[1] + finalTemp;
        }
    }

    private static String getHumText(Context context, boolean isLow, String tempCode){
        String[] mTrigger = context.getResources().getStringArray(R.array.thtrigger_method);
        String[] mStyle = context.getResources().getStringArray(R.array.thtrigger_style);
        if (isLow) {
            return mTrigger[1] + mStyle[0] + Integer.parseInt(tempCode, 16);
        } else {
            return mTrigger[1] + mStyle[1] + Integer.parseInt(tempCode, 16);
        }
    }

    /**
     * 解析温湿度首页显示
     * @param context 上下文
     * @param humiture 温湿度
     * @return 温湿度显示
     */
    public static String getHumitureMsg(Context context, String type, String humiture){
        if (!TextUtils.isEmpty(humiture) && humiture.length()==8) {
            String temp = humiture.substring(4, 6);
            String temp2 = Integer.toBinaryString(Integer.parseInt(temp, 16));
            String humidity = humiture.substring(6, 8);
            String realT;
            String realH;
            if (temp2.length() == 8) {
                realT = "-" + (128 - Integer.parseInt(temp2.substring(1), 2));
            } else {
                realT = Integer.parseInt(temp2, 2) + "";
            }
            if (Integer.parseInt(realT) > 100 || Integer.parseInt(realT) < -40 || Integer.parseInt(humidity, 16) < 0 || Integer.parseInt(humidity, 16) > 100) {
                realT = DeviceStatusUtil.getAlert(context, type, humiture);
                return realT;
            } else {
                realH = Integer.parseInt(humidity, 16) + "";
                return "T:" + realT + "℃" + "\n" + "H:" + realH + "%";
            }
        }else {
            return context.getString(R.string.off_line);
        }
    }

    /**
     * 获取温控器设置数据
     * @param status
     * @return
     */
    public static String getThermostatMsg(Context context, String status){
        String outputCode = status.substring(2,4);
        int code = Integer.parseInt(outputCode, 16);
        String explain = context.getString(R.string.setting);
        if (code>30){
            int temp = code - 32;
            return explain + temp + "." + "5℃";
        }else {
            return explain + code + "℃";
        }
    }

    /**
     * 计算二进制中1出现的位置
     * @param scene
     * @return
     */
    public static String getSceneInAuto(String scene){
        StringBuilder index = new StringBuilder();
        int k = scene.length();
        while (k >= 0) {
            int ind = scene.length() - scene.lastIndexOf("1", k);
            if (ind >= 0) {
                k = scene.lastIndexOf("1", k) - 1;
                index.append(ind-1);
                index.append(",");
            }else {
                break;
            }
        }
        return index.substring(0, index.length()-1);
    }

    /**
     * 解析网关告警记录
     * @param deviceName
     * @param content
     * @return
     */
    public static List<WarnBean> getWarnMsg(String deviceName, String content){
        List<WarnBean> warnBeanList = new ArrayList<>();
        try{
            for (int i = 0; i < content.length() / 30; i++) {
                String code = content.substring(i * 30, (i + 1) * 30);
                String time = code.substring(18, 26);
                BigInteger big = new BigInteger(time.trim(), 16);
                long time1 = big.longValue();
                String type = code.substring(0, 2);
                if ("AD".equals(type)) {
                    int deviceId = Integer.parseInt(code.substring(2, 6), 16);
                    String deviceType = code.substring(6, 10);
                    String deviceStatus = code.substring(10, 18);
                    WarnBean warnBean = new WarnBean();
                    warnBean.setCode(code);
                    warnBean.setTime(time1);
                    warnBean.setType(type);
                    warnBean.setDevice_id(deviceId);
                    warnBean.setDevice_type(deviceType);
                    warnBean.setDevice_status(deviceStatus);
                    warnBean.setDeviceName(deviceName);
                    warnBeanList.add(warnBean);
                } else if ("AC".equals(type)) {
                    int mid = Integer.parseInt(code.substring(2, 6), 16);
                    WarnBean warnBean = new WarnBean();
                    warnBean.setCode(code);
                    warnBean.setTime(time1);
                    warnBean.setType(type);
                    warnBean.setMid(mid);
                    warnBean.setDevice_id(0);
                    warnBean.setDeviceName(deviceName);
                    warnBeanList.add(warnBean);
                }
            }
        }catch (Exception e){
            Log.e("WarnDaoUtil", "increaseWarnMsg: ");
        }
        return warnBeanList;
    }

    /**
     * 解析子设备历史记录
     * @param deviceName
     * @param content
     * @return
     */
    public static List<HistoryBean> getSubHistoryMsg(String deviceName, String content){
        List<HistoryBean> historyList = new ArrayList<>();
        try{
            for (int i = 0; i < content.length() / 24; i++) {
                String c = content.substring(i * 24, (i + 1) * 24);
                String time = c.substring(16, 24);
                BigInteger big = new BigInteger(time.trim(), 16);
                long time1 = big.longValue();
                int deviceId = Integer.parseInt(c.substring(0, 4), 16);
                String deviceType = c.substring(4, 8);
                String deviceStatus = c.substring(8, 16);
                HistoryBean history = new HistoryBean();
                history.setTime(time1);
                history.setDevice_id(deviceId);
                history.setDevice_type(deviceType);
                history.setDevice_status(deviceStatus);
                history.setDeviceName(deviceName);
                history.setCode(c);
                historyList.add(history);
            }
        }catch (Exception e){
            Log.e("HistoryUtil", "increaseSubMsg: ");
        }
        return historyList;
    }

    /**
     * 计算二进制中0出现的位置
     * @param code
     * @return
     */
    public static String getZeroInBinary(String code){
        StringBuilder index = new StringBuilder();
        int k = code.length();
        while (k >= 0) {
            int ind = code.length() - code.lastIndexOf("1", k);
            if (ind >= 0) {
                k = code.lastIndexOf("1", k) - 1;
                index.append(ind-1);
                index.append(",");
            }else {
                break;
            }
        }
        return index.substring(0, index.length()-1);
    }

    /**
     * 获取所有映射场景code
     * @param deviceName 网关
     * @return code
     */
    public static String getAllMappingScene(String deviceName){
        List<Integer> sceneId = SceneDaoUtil.getInstance().findAllSceneId(deviceName);
        int sceneSize = sceneId.size();
        if (sceneSize>0){
            StringBuilder index = new StringBuilder("000000000000");
            for (int i = 0; i < sceneSize; i++) {
                int position = sceneId.get(i);
                index.replace(position, position+1, "1");
            }
            String fullCode = Integer.toHexString(Integer.parseInt(index.reverse().toString(), 2));
            return setCodeSupplement6Byte(fullCode);
        }else {
            return "0000";
        }
    }

    /**
     * 获取修改后的映射场景
     * @param sceneId 当前场景ID
     * @param scene 已存在的场景
     * @return 十六进制
     */
    public static String getNewSceneId(int sceneId, String scene){
        List<String> src = new ArrayList<>();
        if (!"0000".equals(scene)){
            src = getSceneList(scene);
        }
        String current = String.valueOf(sceneId);//当前场景
        if (src.contains(current)){
            src.remove(current);
        }else {
            src.add(current);
        }
        int sceneSize = src.size();
        if (sceneSize > 0) {
            StringBuilder index = new StringBuilder("000000000000");
            for (int i = 0; i < sceneSize; i++) {
                int position = Integer.parseInt(src.get(i));
                index.replace(position, position+1, "1");
            }
            String fullCode = Integer.toHexString(Integer.parseInt(index.reverse().toString(), 2));
            return setCodeSupplement2Byte(fullCode);
        }else {
            return "0000";
        }
    }

    /**
     * 获取已映射的场景ID
     * @param scene
     * @return
     */
    public static List<String> getSceneList(String scene){
        if (!TextUtils.isEmpty(scene)) {
            String mScene = Integer.toBinaryString(Integer.parseInt(scene, 16));
            String[] allScene = getSceneInAuto(mScene).split(",");
            return new ArrayList<>(Arrays.asList(allScene));
        }
        return new ArrayList<>();
    }

    /**
     * String转Ascii
     * @param input 输入名称
     * @return Ascii
     */
    public static String getAscii(String input){
        int countf = 0;

        try {
            countf = 15 - input.getBytes("GBK").length;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        StringBuffer buffer = new StringBuffer();
        for(int i=0;i<countf;i++){
            buffer.append("@");
        }
        String newName = buffer.toString()+input+"$";

        byte[] nameBt = new byte[16];
        try {
            nameBt = newName.getBytes("GBK");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        StringBuilder ds = new StringBuilder();
        for(int i=0;i<nameBt.length;i++){
            String str = ByteUtil.convertByte2HexString(nameBt[i]);
            ds.append(str);
        }
        return ds.toString();
    }

    /**
     * Ascii转String
     * @param input 输入Ascii
     * @return String
     */
    public static String getStringFromAscii(String input){
        try {
            if(input.length()!=32){
                return "";
            }
            byte[]a = ByteUtil.hexStr2Bytes(input);
            String name  = new String(a,"GBK");
            if(!name.contains("$")){
                return "";
            }
            int index = -1;
            if(name.contains("@")){
                index = name.lastIndexOf("@");
            }

            return  name.substring(index + 1, name.indexOf("$"));

        }catch (Exception e){
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 解析星期
     * @param context
     * @param week
     * @return
     */
    public static String getWeekInfo(Context context, String week){
        try {
            StringBuilder weekTime = new StringBuilder();
            byte ds = ByteUtil.hexStr2Bytes(week)[0];
            byte f;
            for(int i=0;i<7;i++){
                f =   (byte)((0x02 << i) & ds);
                if(f!=0){
                    weekTime.append(context.getResources().getStringArray(R.array.week_day2)[i]).append(" 、");
                }
            }
            weekTime = new StringBuilder(weekTime.substring(0, weekTime.length() - 1));
            return weekTime.toString();
        }catch (Exception e){
            return "";
        }
    }

    /**
     * 解析设备应答
     * @param str1 cmd
     * @param str2 结果 success/fail
     * @return 1成功/0失败
     */
    public static int getAnswerResult(String str1, String str2){
        if (str1.length() == 9){
            int cmd = Integer.parseInt(str1.substring(0, 4), 16);
            switch (cmd){
                case SiterCommand.EQUIPMENT_CONTROL:
                    return CommonId.KEY_SUCCESS.equals(str2)? 1 : 0;
                case SiterCommand.DELETE_EQUIPMENT:
                    return CommonId.KEY_SUCCESS.equals(str2)? 4 : 0;
                case SiterCommand.MODIFY_EQUIPMENT_NAME:
                    return CommonId.KEY_SUCCESS.equals(str2)? 5 : 0;
                case SiterCommand.CHOOSE_SCENE:
                    return CommonId.KEY_SUCCESS.equals(str2)? 6 : 0;
                case SiterCommand.INCREASE_AUTOMATION:
                    return CommonId.KEY_SUCCESS.equals(str2.substring(0, 2))? 8 : 0;
                case SiterCommand.DELETE_AUTOMATION:
                    return 10;
                case SiterCommand.DELETE_SCENE:
                    return CommonId.KEY_SUCCESS.equals(str2)? 39 : 0;
            }
        }
        return -1;
    }

    /**
     * 代码补充0(2byte)
     * @param code
     * @return
     */
    public static String setCodeSupplement2Byte(String code){
        StringBuilder zero = new StringBuilder("0");
        String newCode;
        int totalLength = code.length() ;
        if (totalLength < 4) {
            for (int i = 0; i < 4 - totalLength -1; i++) {
                zero.append(0);
            }
            newCode = zero + code;
        } else {
            newCode = code;
        }
        return newCode;
    }

    /**
     * 代码补充0（1byte)
     * @param code
     * @return
     */
    public static String setCodeSupplement1Byte(String code){
        StringBuilder zero = new StringBuilder("0");
        String newCode;
        int totalLength = code.length() ;
        if (totalLength < 2) {
            for (int i = 0; i < 2 - totalLength -1; i++) {
                zero.append(0);
            }
            newCode = zero + code;
        } else {
            newCode = code;
        }
        return newCode;
    }

    /**
     * 代码补充0(2byte)
     * @param code
     * @return
     */
    public static String setCodeSupplement4Byte(String code){
        StringBuilder zero = new StringBuilder("0");
        String newCode;
        int totalLength = code.length() ;
        if (totalLength < 8) {
            for (int i = 0; i < 8 - totalLength -1; i++) {
                zero.append(0);
            }
            newCode = zero + code;
        } else {
            newCode = code;
        }
        return newCode;
    }

    /**
     * 代码补充0（6byte)
     * @param code
     * @return
     */
    public static String setCodeSupplement6Byte(String code){
        StringBuilder zero = new StringBuilder("0");
        String newCode;
        int totalLength = code.length() ;
        if (totalLength < 12) {
            for (int i = 0; i < 12 - totalLength -1; i++) {
                zero.append(0);
            }
            newCode = zero + code;
        } else {
            newCode = code;
        }
        return newCode;
    }
}
